package com.study.utils;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component("transactionUtil")
@Aspect
public class TransactionUtil {
    @Pointcut("execution(* com.study.service.impl.*.*(..))")
    public void pc() {
    }

    @Autowired
    private ConnectionUtil connectionUtil;

    public void setConnectionUtil(ConnectionUtil connectionUtil) {
        this.connectionUtil = connectionUtil;
    }

    //    @Before("pc()")
    public void beginTransaction() {
        try {
            System.out.println("开启事务");
            connectionUtil.getLocalThreadConnection().setAutoCommit(false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //    @After("pc()")
    public void commitTransaction() {
        try {
            System.out.println("提交事务");
            connectionUtil.getLocalThreadConnection().commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //    @AfterThrowing("pc()")
    public void rollbackTransaction() {
        try {
            System.out.println("回退事务");
            connectionUtil.getLocalThreadConnection().rollback();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //    @AfterReturning("pc()")
    public void releaseTransaction() {
        try {
            System.out.println("释放事务");
            connectionUtil.getLocalThreadConnection().close();
            connectionUtil.removeLocalThreadConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Around("pc()")
    public Object aroundAdvice(ProceedingJoinPoint pjp) {
        Object rv = null;
        try {
            this.beginTransaction();
            rv = pjp.proceed(pjp.getArgs());
            this.commitTransaction();


        } catch (Throwable e) {
            e.printStackTrace();
            this.rollbackTransaction();

        } finally {
            this.releaseTransaction();
        }
        return rv;

    }
}
